home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SNIP0492.ARJ / MSD_DIR.C < prev    next >
C/C++ Source or Header  |  1991-10-03  |  6KB  |  221 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06   Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8.  
  9. #include        <sys/types.h>
  10. #include        <sys/stat.h>
  11. #include        <sys/dir.h>
  12. #include        <malloc.h>
  13. #include        <string.h>
  14. #include        <dos.h>
  15.  
  16. #ifndef NULL
  17. # define        NULL    0
  18. #endif  /* NULL */
  19.  
  20. #ifndef MAXPATHLEN
  21. # define        MAXPATHLEN      255
  22. #endif  /* MAXPATHLEN */
  23.  
  24. /* attribute stuff */
  25. #define A_RONLY         0x01
  26. #define A_HIDDEN        0x02
  27. #define A_SYSTEM        0x04
  28. #define A_LABEL         0x08
  29. #define A_DIR           0x10
  30. #define A_ARCHIVE       0x20
  31.  
  32. /* dos call values */
  33. #define DOSI_FINDF      0x4e
  34. #define DOSI_FINDN      0x4f
  35. #define DOSI_SDTA       0x1a
  36.  
  37. #define Newisnull(a, t)         ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  38. #define ATTRIBUTES              (A_DIR | A_HIDDEN | A_SYSTEM)
  39.  
  40. /* what find first/next calls look use */
  41. typedef struct {
  42.         char            d_buf[21];
  43.         char            d_attribute;
  44.         unsigned short  d_time;
  45.         unsigned short  d_date;
  46.         long            d_size;
  47.         char            d_name[13];
  48. } Dta_buf;
  49.  
  50. static  char    *getdirent();
  51. static  void    setdta();
  52. static  void    free_dircontents();
  53.  
  54. static  Dta_buf         dtabuf;
  55. static  Dta_buf         *dtapnt = &dtabuf;
  56. static  union REGS      reg, nreg;
  57.  
  58. #if     defined(M_I86LM)
  59. static  struct SREGS    sreg;
  60. #endif
  61.  
  62. DIR     *
  63. opendir(name)
  64.         char    *name;
  65. {
  66.         struct  stat            statb;
  67.         DIR                     *dirp;
  68.         char                    c;
  69.         char                    *s;
  70.         struct _dircontents     *dp;
  71.         char                    nbuf[MAXPATHLEN + 1];
  72.         
  73.         strcpy(nbuf, name);
  74.         if ((s = strrchr(nbuf, '/')) != (char *) NULL)
  75.                 *s = '\0';
  76.         else if ((s = strrchr(nbuf, '\\')) != (char *) NULL)
  77.                 *s = '0';
  78.         if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  79.                 return (DIR *) NULL;
  80.         if (Newisnull(dirp, DIR))
  81.                 return (DIR *) NULL;
  82.         if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  83.                 (void) strcat(strcpy(nbuf, name), "\\*.*");
  84.         else
  85.                 (void) strcat(strcpy(nbuf, name), "*.*");
  86.         dirp->dd_loc = 0;
  87.         setdta();
  88.         dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  89.         if ((s = getdirent(nbuf)) == (char *) NULL)
  90.                 return dirp;
  91.         do {
  92.                 if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  93.                         malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  94.                 {
  95.                         if (dp)
  96.                                 free((char *) dp);
  97.                         free_dircontents(dirp->dd_contents);
  98.                         return (DIR *) NULL;
  99.                 }
  100.                 if (dirp->dd_contents)
  101.                         dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  102.                 else
  103.                         dirp->dd_contents = dirp->dd_cp = dp;
  104.                 (void) strcpy(dp->_d_entry, s);
  105.                 dp->_d_next = (struct _dircontents *) NULL;
  106.         } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  107.         dirp->dd_cp = dirp->dd_contents;
  108.  
  109.         return dirp;
  110. }
  111.  
  112. void
  113. closedir(dirp)
  114.         DIR     *dirp;
  115. {
  116.         free_dircontents(dirp->dd_contents);
  117.         free((char *) dirp);
  118. }
  119.  
  120. struct direct   *
  121. readdir(dirp)
  122.         DIR     *dirp;
  123. {
  124.         static  struct direct   dp;
  125.         
  126.         if (dirp->dd_cp == (struct _dircontents *) NULL)
  127.                 return (struct direct *) NULL;
  128.         dp.d_namlen = dp.d_reclen =
  129.                 strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  130.         strlwr(dp.d_name);
  131.         dp.d_ino = 0;
  132.         dirp->dd_cp = dirp->dd_cp->_d_next;
  133.         dirp->dd_loc++;
  134.  
  135.         return &dp;
  136. }
  137.  
  138. void
  139. seekdir(dirp, off)
  140.         DIR     *dirp;
  141.         long    off;
  142. {
  143.         long                    i = off;
  144.         struct _dircontents     *dp;
  145.  
  146.         if (off < 0)
  147.                 return;
  148.         for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  149.                 ;
  150.         dirp->dd_loc = off - (i + 1);
  151.         dirp->dd_cp = dp;
  152. }
  153.  
  154. long
  155. telldir(dirp)
  156.         DIR     *dirp;
  157. {
  158.         return dirp->dd_loc;
  159. }
  160.  
  161. static  void
  162. free_dircontents(dp)
  163.         struct  _dircontents    *dp;
  164. {
  165.         struct _dircontents     *odp;
  166.  
  167.         while (dp) {
  168.                 if (dp->_d_entry)
  169.                         free(dp->_d_entry);
  170.                 dp = (odp = dp)->_d_next;
  171.                 free((char *) odp);
  172.         }
  173. }
  174.  
  175. static  char    *
  176. getdirent(dir)
  177.         char    *dir;
  178. {
  179.         if (dir != (char *) NULL) {             /* get first entry */
  180.                 reg.h.ah = DOSI_FINDF;
  181.                 reg.h.cl = ATTRIBUTES;
  182. #if     defined(M_I86LM)
  183.                 reg.x.dx = FP_OFF(dir);
  184.                 sreg.ds = FP_SEG(dir);
  185. #else
  186.                 reg.x.dx = (unsigned) dir;
  187. #endif
  188.         } else {                                /* get next entry */
  189.                 reg.h.ah = DOSI_FINDN;
  190. #if     defined(M_I86LM)
  191.                 reg.x.dx = FP_OFF(dtapnt);
  192.                 sreg.ds = FP_SEG(dtapnt);
  193. #else
  194.                 reg.x.dx = (unsigned) dtapnt;
  195. #endif
  196.         }
  197. #if     defined(M_I86LM)
  198.         intdosx(®, &nreg, &sreg);
  199. #else
  200.         intdos(®, &nreg);
  201. #endif
  202.         if (nreg.x.cflag)
  203.                 return (char *) NULL;
  204.  
  205.         return dtabuf.d_name;
  206. }
  207.  
  208. static  void
  209. setdta()
  210. {
  211.         reg.h.ah = DOSI_SDTA;
  212. #if     defined(M_I86LM)
  213.         reg.x.dx = FP_OFF(dtapnt);
  214.         sreg.ds = FP_SEG(dtapnt);
  215.         intdosx(®, &nreg, &sreg);
  216. #else
  217.         reg.x.dx = (int) dtapnt;
  218.         intdos(®, &nreg);
  219. #endif
  220. }
  221.